package com.project.service.impl;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ServiceProxyFactory implements InvocationHandler {
    private Object target;
    private static SqlSessionFactory factory;
    static{
        try {
            Reader r = Resources.getResourceAsReader("mybatis.cfg.xml");
            factory = new SqlSessionFactoryBuilder().build(r);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public ServiceProxyFactory(Object target){
        this.target=target;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        SqlSession session = factory.openSession();
        //得到目标对象属性列表
        Field[] fieldArray = target.getClass().getDeclaredFields();
        for (Field f: fieldArray){
            //判断属性是否为接口
            if(f.getType().isInterface()){
                //产生接口实现类对象
                Object mapper = session.getMapper(f.getType());
                f.setAccessible(true);
                //给mapper属性赋值
                f.set(target,mapper);
            }
        }
        //执行目标方法，得到返回值
        Object returnObj = null;
        try {
            returnObj = method.invoke(target, args);
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally{
            session.close();
        }


        return returnObj;
    }
}
